package org.fu.crowd.mvc.config;

import com.google.gson.Gson;
import org.fu.crowd.constant.CrowdConstant;
import org.fu.crowd.entity.Common;
import org.fu.crowd.exception.LoginFailedException;
import org.fu.crowd.exception.SaveAdminException;
import org.fu.crowd.utils.CrowdUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@ControllerAdvice//表示当前类是一个基于注解的异常处理器类
public class CrowdExceptionResolver {

    //将一个具体的异常类型和一个方法关联起来
    @ExceptionHandler(value = NullPointerException.class)
    public ModelAndView resolveNullPointerException(
            NullPointerException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        return resolveUtils(exception, request, response,"system-error");
    }


    /**
     *  登录异常
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolveLoginFailedException(
            LoginFailedException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        System.out.println("登录失败");
        return resolveUtils(exception, request, response,"admin-login");
    }


    @ExceptionHandler(value = InternalAuthenticationServiceException.class)
    public ModelAndView internalAuthenticationServiceException(
            InternalAuthenticationServiceException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        System.out.println("登录失败");
        return resolveUtils(exception, request, response,"admin-login");
    }


    /**
     *                  插入数据异常    账户已存在
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = SaveAdminException.class)
    public ModelAndView sqlIntegrityConstraintViolationException(
            SaveAdminException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        return resolveUtils(exception, request, response,"addUser");
    }

    /**
     *                  插入数据异常    账户已存在
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = DuplicateKeyException.class)
    public ModelAndView DuplicateKeyException(
            DuplicateKeyException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        return resolveUtils(exception, request, response,"addUser");
    }





    @ExceptionHandler(value = RuntimeException.class)
    public ModelAndView resolveRuntimeException(
            RuntimeException exception,
            HttpServletRequest request,
            HttpServletResponse response) throws IOException {

        return resolveUtils(exception, request, response,"admin-login");
    }


    /**
     *  工具类
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    private ModelAndView resolveUtils(Exception exception, HttpServletRequest request, HttpServletResponse response, String viewName) throws IOException {
        boolean b = CrowdUtils.judgeRequestType(request);
        if (b){
            Common failed = Common.failed(exception.getMessage());
            Gson gson = new Gson();
            String s = gson.toJson(failed);
            response.getWriter().write(s);
            return null;
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION,exception.getMessage());
        modelAndView.setViewName(viewName);
        return modelAndView;
    }

}
